# coding:utf-8
from django.db import transaction
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from MSB_ERP.utils.get_inventory import get_inventory
from warehouse_info.models import PurchaseStorageModel, PurchaseStorageItemModel


class InStorageItemSerializer(serializers.ModelSerializer):
    # 注意：只有库存数据没有，那么可以增加一个属性
    cur_inventory = serializers.SerializerMethodField(read_only=True, label='在当前仓库的库存')

    class Meta:
        model = PurchaseStorageItemModel
        fields = '__all__'

    def get_cur_inventory(self, obj):
        result = get_inventory(obj.goods.id, obj.warehouse.id)
        return result if result else 0


class InStorageSerializer(serializers.ModelSerializer):
    """
    入库单--反序列化器（用于新增和修改） 和 查询列表的序列化器（用于入库单列表）
    """
    item_list = InStorageItemSerializer(many=True)
    # 商品信息：商品名称,商品的规格
    goods_info = serializers.SerializerMethodField(read_only=True, label='入库单每个商品信息')

    class Meta:
        model = PurchaseStorageModel
        fields = '__all__'

    def get_goods_info(self, obj):
        # 商品信息是：商品名字+商品规格
        if obj.item_list.all():
            reuslt = []
            for item in obj.item_list.all():
                reuslt.append(item.name + (item.specification if item.specification else ''))
            return ','.join(reuslt)  # 把列表元素展开用,隔开
        return ''

    def create(self, validated_data):
        # 由于插入入库单和入库单中的货品项，必须重写create
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            # 新增入库单
            in_storage = PurchaseStorageModel.objects.create(**validated_data)
            for item in item_list:
                psi = PurchaseStorageItemModel.objects.create(purchase_storage=in_storage, **item)
                # 把一些冗余的属性加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
        return in_storage

    #   instance就是正在修改的入库单
    def update(self, instance, validated_data):
        # 修改的条件
        if instance.status != '0':
            raise ValidationError('不能修改')
        item_list = validated_data.pop('item_list')  # 请求参数中的入库项目数据
        old_list = instance.item_list.all()  # 从数据库中查询出旧的入库项目数据
        with transaction.atomic():
            if old_list.exists():
                # 删除旧的入库项目数据库
                old_list.delete()

            for item in item_list:
                psi = PurchaseStorageItemModel.objects.create(purchase_storage=instance, **item)
                # 把一些冗余的属性加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
            result = super(InStorageSerializer, self).update(instance=instance, validated_data=validated_data)
        return result


# 用于查询单个入库单的序列化器
class InStorageGetSerializer(serializers.ModelSerializer):
    # 仅仅用于查询单个入库单的序列化器
    # 注意：只有库存数据，在PurchaseStorageItemModel没有，这就是冗余字段多的好处
    item_list = InStorageItemSerializer(many=True, read_only=True)

    class Meta:
        model = PurchaseStorageModel
        fields = '__all__'
